package com.ttn.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ttn.business.mapper.CourseUnitHearingMapper;
import com.ttn.business.service.CourseUnitHearingDetailsService;
import com.ttn.business.service.CourseUnitHearingService;
import com.ttn.common.core.entity.PageQuery;
import com.ttn.common.core.entity.Result;
import com.ttn.common.core.entity.business.CourseUnitHearing;
import com.ttn.common.core.entity.business.CourseUnitHearingDetails;
import com.ttn.common.core.entity.business.bo.CourseUnitHearingBO;
import com.ttn.common.core.entity.business.converter.CourseUnitHearingConverter;
import com.ttn.common.core.entity.business.vo.CourseUnitHearingVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class CourseUnitHearingServiceImpl extends ServiceImpl<CourseUnitHearingMapper, CourseUnitHearing> implements CourseUnitHearingService {

    @Resource
    private CourseUnitHearingMapper courseUnitHearingMapper;
    @Resource
    private CourseUnitHearingDetailsService courseUnitHearingDetailsService;

    @Override
    @Transactional
    public Result saveCourseUnitHearing(CourseUnitHearingBO courseUnitHearingBO) {
        CourseUnitHearing courseUnitHearing = new CourseUnitHearing();
        courseUnitHearing.setCourseUnitId(courseUnitHearingBO.getCourseUnitId());
        courseUnitHearing.setAudioFile(courseUnitHearingBO.getAudioFile());
        LambdaQueryWrapper<CourseUnitHearing> courseUnitHearingLambdaQueryWrapper = new LambdaQueryWrapper();
        courseUnitHearingLambdaQueryWrapper.eq(CourseUnitHearing::getCourseUnitId, courseUnitHearing.getCourseUnitId());
        courseUnitHearing.setSort(Math.toIntExact(this.count(courseUnitHearingLambdaQueryWrapper)) + 1);
        this.save(courseUnitHearing);
        courseUnitHearingBO.getCourseUnitHearingDetailsList().stream().forEach(courseUnitHearingDetails -> {
            courseUnitHearingDetails.setCourseUnitHearingId(courseUnitHearing.getId());
        });
        if (courseUnitHearingBO.getCourseUnitHearingDetailsList().size() > 0) {
            AtomicInteger questionNumber = new AtomicInteger(1);
            courseUnitHearingBO.getCourseUnitHearingDetailsList().stream().forEach(courseUnitHearingDetails -> {
                courseUnitHearingDetails.setQuestionNumber(questionNumber.getAndIncrement());

            });
            courseUnitHearingDetailsService.saveBatch(courseUnitHearingBO.getCourseUnitHearingDetailsList());
        }

        return Result.success();
    }

    @Override
    public Result modifyCourseUnitHearing(CourseUnitHearingBO courseUnitHearingBO) {


        CourseUnitHearing courseUnitHearing = new CourseUnitHearing();
        courseUnitHearing.setId(courseUnitHearingBO.getId());
        courseUnitHearing.setAudioFile(courseUnitHearingBO.getAudioFile());
        this.updateById(courseUnitHearing);

        if (courseUnitHearingBO.getCourseUnitHearingDetailsList().size() > 0) {
            List<Integer> detailsIds = courseUnitHearingBO.getCourseUnitHearingDetailsList().stream().map(CourseUnitHearingDetails::getId).collect(Collectors.toList());

            if (detailsIds.size() > 0) {
                LambdaQueryWrapper<CourseUnitHearingDetails> courseUnitHearingDetailsLambdaQueryWrapper = new LambdaQueryWrapper<>();
                courseUnitHearingDetailsLambdaQueryWrapper.eq(CourseUnitHearingDetails::getCourseUnitHearingId, courseUnitHearingBO.getId());
                courseUnitHearingDetailsLambdaQueryWrapper.notIn(CourseUnitHearingDetails::getId,
                        courseUnitHearingBO.getCourseUnitHearingDetailsList().stream().map(CourseUnitHearingDetails::getId
                        ).collect(Collectors.toList()));
                List<CourseUnitHearingDetails> courseUnitHearingDetailsList =
                        courseUnitHearingDetailsService.list(courseUnitHearingDetailsLambdaQueryWrapper);
                if (courseUnitHearingDetailsList.size() > 0) {
                    courseUnitHearingDetailsService.removeBatchByIds(courseUnitHearingDetailsList);
                }
            }
            AtomicInteger questionNumber = new AtomicInteger(1);
            courseUnitHearingBO.getCourseUnitHearingDetailsList().stream().forEach(courseUnitHearingDetails -> {
                courseUnitHearingDetails.setQuestionNumber(questionNumber.getAndIncrement());

            });
            courseUnitHearingDetailsService.saveOrUpdateBatch(courseUnitHearingBO.getCourseUnitHearingDetailsList());
        }
        return Result.success();
    }


    @Override
    @Transactional
    public Result deleteCourseUnitHearingById(Integer id) {
        CourseUnitHearing courseUnitHearing = this.getById(id);
        this.removeById(id);
        LambdaQueryWrapper<CourseUnitHearingDetails> courseUnitHearingDetailsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseUnitHearingDetailsLambdaQueryWrapper.eq(CourseUnitHearingDetails::getCourseUnitHearingId, id);
        courseUnitHearingDetailsService.remove(courseUnitHearingDetailsLambdaQueryWrapper);
        LambdaQueryWrapper<CourseUnitHearing> courseUnitHearingLambdaQueryWrapper = new LambdaQueryWrapper();
        courseUnitHearingLambdaQueryWrapper.ne(CourseUnitHearing::getId, id);
        courseUnitHearingLambdaQueryWrapper.eq(CourseUnitHearing::getCourseUnitId, courseUnitHearing.getCourseUnitId());
        courseUnitHearingLambdaQueryWrapper.orderByAsc(CourseUnitHearing::getSort);
        List<CourseUnitHearing> courseUnitHearingList = this.list(courseUnitHearingLambdaQueryWrapper);
        if (courseUnitHearingList.size() > 0) {
            AtomicInteger i = new AtomicInteger(1);
            courseUnitHearingList.stream().forEach(courseUnitHearing1 -> {
                courseUnitHearing1.setSort(i.getAndIncrement());
            });
            this.updateBatchById(courseUnitHearingList);
        }
        return Result.success();
    }

    @Override
    public Result queryCourseUnitHearingById(Integer id) {
        CourseUnitHearingVO courseUnitHearingVO = new CourseUnitHearingVO();
        CourseUnitHearing courseUnitHearing = this.getById(id);
        if (Objects.nonNull(courseUnitHearing)) {
            courseUnitHearingVO.setId(courseUnitHearing.getId());
            courseUnitHearingVO.setAudioFile(courseUnitHearing.getAudioFile());
            courseUnitHearingVO.setCourseUnitId(courseUnitHearing.getCourseUnitId());
            LambdaQueryWrapper<CourseUnitHearingDetails> courseUnitHearingDetailsLambdaQueryWrapper = new LambdaQueryWrapper<>();
            courseUnitHearingDetailsLambdaQueryWrapper.eq(CourseUnitHearingDetails::getCourseUnitHearingId, id);
            courseUnitHearingVO.setCourseUnitHearingDetailsList(courseUnitHearingDetailsService.list(courseUnitHearingDetailsLambdaQueryWrapper));
        }
        return Result.success(courseUnitHearingVO);
    }

    @Override
    public Result queryCourseUnitHearingByCourseUnitIdPage(Integer courseUnitId, PageQuery pageQuery) {
        IPage<CourseUnitHearing> courseUnitHearingPage = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
        LambdaQueryWrapper<CourseUnitHearing> courseUnitHearingLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseUnitHearingLambdaQueryWrapper.eq(CourseUnitHearing::getCourseUnitId, courseUnitId);
        courseUnitHearingLambdaQueryWrapper.orderByAsc(CourseUnitHearing::getSort);
        Page<CourseUnitHearingVO> courseUnitHearingVOPage = CourseUnitHearingConverter.INSTANCE.courseUnitHearing2VOPage(this.page(courseUnitHearingPage, courseUnitHearingLambdaQueryWrapper));
        if (Objects.nonNull(courseUnitHearingVOPage) && courseUnitHearingVOPage.getRecords().size() > 0) {
            List<Integer> courseUnitHearingIdList = courseUnitHearingVOPage.getRecords().stream().map(CourseUnitHearingVO::getId).collect(Collectors.toList());
            if (courseUnitHearingIdList.size() > 0) {
                LambdaQueryWrapper<CourseUnitHearingDetails> courseUnitHearingDetailsLambdaQueryWrapper = new LambdaQueryWrapper<>();
                courseUnitHearingDetailsLambdaQueryWrapper.in(CourseUnitHearingDetails::getCourseUnitHearingId, courseUnitHearingIdList);
                List<CourseUnitHearingDetails> courseUnitHearingDetailsList = courseUnitHearingDetailsService.list(courseUnitHearingDetailsLambdaQueryWrapper);
                if (courseUnitHearingDetailsList.size() > 0) {
                    courseUnitHearingVOPage.getRecords().stream().forEach(courseUnitHearingVO -> {
                        courseUnitHearingVO.setCourseUnitHearingDetailsList(courseUnitHearingDetailsList.stream().filter(courseUnitHearingDetails -> Objects.equals(courseUnitHearingVO.getId(), courseUnitHearingDetails.getCourseUnitHearingId())).collect(Collectors.toList()));
                        courseUnitHearingVO.getCourseUnitHearingDetailsList().sort(Comparator.comparing(CourseUnitHearingDetails::getQuestionNumber));
                    });
                }
            }
        }
        return Result.success(courseUnitHearingVOPage);
    }
}
